#pragma once

#include <iostream>
#include "Socket.hpp"
#include <memory>
#include<functional>
#include<sys/wait.h>

namespace TcpServerModule
{
    using namespace SocketModule;
    using namespace LogModule;
    using tcphandler_t = std::function<bool(SockPtr,InetAddr)>;

    //服务器只负责I/O,流式的I/O，不对协议进行任何处理
    class TcpServer
    {
    public:
        TcpServer(int port)
        :_listensockp(make_unique<TcpSocket>()),_running(false),_port(port)
        {
        }

        void InitServer(tcphandler_t handler)
        {
           _handler = handler;
            _listensockp->BuildTcpSocket(_port); //listen套接字就全有了
        }

        void Loop()
        {
            _running = true; 
             while(_running)
             {
                //1.获取链接Accept
                
                InetAddr clientaddr;
                LOG(LogLevel::DEBUG) << " accept..\n";
                auto sockfd = _listensockp->Accepter(&clientaddr);
                LOG(LogLevel::DEBUG) << " accept ok..\n";
                if(sockfd == nullptr) continue ;//重新获取新链接
                //2. I/O处理
                LOG(LogLevel::DEBUG) << "get a new client, info is: " <<clientaddr.Addr();
                // sockfd->Recv(); 
                // sockfd->Send();
                pid_t id = fork();
                if(id == 0)
                {
                    _listensockp->Close(); //关闭不需要的
                    if(fork() > 0) exit(0);
                    _handler(sockfd,clientaddr); 
                    exit(0); //处理完就退出
                }
                sockfd->Close();
                waitpid(id,nullptr,0);
                    
             }
        }

        ~TcpServer()
        {
            _listensockp->Close();
        }

    private:
        // 一定要有listensockfd
        unique_ptr<Socket> _listensockp;
        bool _running;
        tcphandler_t _handler;
        int _port;
    };

}